package com.haiqiu.common.utils.tools;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import lombok.extern.log4j.Log4j2;
import com.haiqiu.common.easypoi.ExcelStyleUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * @Description Excel导入导出工具类
 * @Author chengkun
 * @Date 2020/3/17 19:40
 **/
@Log4j2
@SuppressWarnings("all")
public class ExcelUtil {
    /**
     * 功能描述：复杂导出Excel，包括文件名以及表名。创建表头
     *
     * @param list           导出的实体类
     * @param title          表头名称
     * @param sheetName      sheet表名
     * @param pojoClass      映射的实体类
     * @param isCreateHeader 是否创建表头
     * @param fileName
     * @param response
     * @return
     * @Author chengkun
     * @Date 2020/3/17 19:40
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setCreateHeadRows(isCreateHeader);
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    /**
     * @Description 自定义样式导出
     * @Author chengkun
     * @Date 2020/3/18 9:05
     * @Param list          导出的实体类
     * @Param title         表头名称
     * @Param sheetName     sheet表名
     * @Param pojoClass     映射的实体类
     * @Param fileName      文件名称
     * @Param style         导出样式
     * @Param response
     * @Return void
     **/
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, Class<?> style, HttpServletResponse response) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setStyle(style);
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
            downLoadExcel(fileName, response, workbook);
        }
    }

    /**
     * @Description 自定义样式导出
     * @Author chengkun
     * @Date 2020/3/18 9:05
     * @Param list          导出的实体类
     * @Param title         表头名称
     * @Param sheetName     sheet表名
     * @Param entityList     map标题映射
     * @Param fileName      文件名称
     * @Param style         导出样式
     * @Param response
     * @Return void
     **/
    public static void exportExcel(List<?> list, String title, String sheetName, List<ExcelExportEntity> entityList, String fileName, Class<?> style, HttpServletResponse response) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setStyle(style);
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, list);
        if (workbook != null) {
            downLoadExcel(fileName, response, workbook);
        }
    }

    /**
     * 功能描述：复杂导出Excel，包括文件名以及表名,不创建表头
     *
     * @param list      导出的实体类
     * @param title     表头名称
     * @param sheetName sheet表名
     * @param pojoClass 映射的实体类
     * @param fileName
     * @param response
     * @return
     * @Author chengkun
     * @Date 2020/3/17 19:40
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) {
        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
    }


    /**
     * 导出流表格
     * @param list 数据
     * @param title 标题
     * @param sheetName sheet名
     * @param pojoClass 实体
     * @param fileName 文件名称
     * @param response 输出
     * @return
     */
    public static InputStream inputStreamExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName,
                                          HttpServletResponse response) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        //设置样式
        exportParams.setStyle(ExcelStyleUtil.class);
        return inputstreamDefaultExport(list, pojoClass, fileName, response,exportParams);
    }

    private static InputStream  inputstreamDefaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
            return inputstreamDownloadExcel(fileName, response, workbook);
        }
        return null;
    }

    public static InputStream  inputstreamDownloadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            workbook.write(os);
            os.flush();
            os.close();
            workbook.close();
            return new ByteArrayInputStream(os.toByteArray());
//            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 功能描述：Map 集合导出
     *
     * @param list     实体集合
     * @param fileName 导出的文件名称
     * @param response
     * @return
     * @author 李家威
     * @date 2018/7/23 16:14
     */
    public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        defaultExport(list, fileName, response);
    }

    /**
     * 功能描述：默认导出方法
     *
     * @param list         导出的实体集合
     * @param fileName     导出的文件名
     * @param pojoClass    pojo实体
     * @param exportParams ExportParams封装实体
     * @param response
     * @return
     * @Author chengkun
     * @Date 2020/3/17 19:40
     */
    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
            downLoadExcel(fileName, response, workbook);
        }
    }

    /**
     * 功能描述：Excel导出
     *
     * @param fileName 文件名称
     * @param response
     * @param workbook Excel对象
     * @return
     * @Author chengkun
     * @Date 2020/3/17 19:40
     */
    public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 功能描述：默认导出方法
     *
     * @param list     导出的实体集合
     * @param fileName 导出的文件名
     * @param response
     * @return
     * @Author chengkun
     * @Date 2020/3/17 19:40
     */
    private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
        if (workbook != null) ;
        downLoadExcel(fileName, response, workbook);
    }


    /**
     * 功能描述：根据文件路径来导入Excel
     *
     * @param filePath   文件路径
     * @param titleRows  表标题的行数
     * @param headerRows 表头行数
     * @param pojoClass  Excel实体类
     * @return
     * @Author chengkun
     * @Date 2020/3/17 19:40
     */
    public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
        //判断文件是否存在
        if (StringUtils.isBlank(filePath)) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new RuntimeException("模板不能为空");
        } catch (Exception e) {
            e.printStackTrace();

        }
        return list;
    }

    /**
     * 功能描述：根据接收的Excel文件来导入Excel,并封装成实体类
     *
     * @param file       上传的文件
     * @param titleRows  表标题的行数
     * @param headerRows 表头行数
     * @param pojoClass  Excel实体类
     * @return
     * @Author chengkun
     * @Date 2020/3/17 19:40
     */
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
        if (file == null) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new RuntimeException("excel文件不能为空");
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());

        }
        return list;
    }

    public static void downloadExcel(String name,InputStream is,HttpServletResponse response) throws IOException {
        String usrHome = System.getProperty("user.home");
        String path = usrHome + File.separator + name;
        try {
            OutputStream outputStream = new FileOutputStream(path);
            // 设置输出的格式
            String fileName = URLEncoder.encode(name, "UTF-8");
            //自定义的header
            response.setHeader("requestType","file");
            // 自定义的header
            response.setHeader("requestFileName",fileName);
            //设置这个header 可见
            response.setHeader("Access-Control-Expose-Headers", "requestType,requestFileName");

            //设置响应类型为html，编码为utf-8，处理相应页面文本显示的乱码
            response.setContentType("application/octet-stream;charset=UTF-8");
            //设置文件头：最后一个参数是设置下载文件名
            response.setHeader("Content-disposition", "attachment;fileName=" + fileName);

            int ch = 0;
            while ((ch = is.read()) != -1) {
                outputStream.write(ch);
                response.getOutputStream().write(ch);
            }
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            is.close();
            File file = new File(path);
            if (file.exists()){
                file.delete();
            }
            System.out.println("Excel导出完成");
        }
    }

}